/*
 * Copyright 2011-2012 OpenAjax Alliance
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

// Components.utils.import("resource://oaa-cache-inspector/cache-inspector-common.js");

/* ---------------------------------------------------------------- */
/*                  Initialize namespace properties                 */
/* ---------------------------------------------------------------- */

if (typeof OAA_CI === "undefined") {
  var OAA_CI = {};
}

if (typeof OAA_CI.Properties === "undefined") {
  OAA_CI.Properties = {};
}

/**
 * @function ruleSelectionChange
 *
 * @memberOf OAA_CI.Properties
 *
 * @desc Updates rule information when a rule is selected in the Rule Results panel
 */
 
OAA_CI.Properties.ruleSelectionChange = function () {

  var rules_tab  = OAA_CI.Properties.properties_panel.rules_tab;
  var index;
  
  if (!rules_tab) return;
  
  var cache_item   = rules_tab.current_cache_item;
  var node_results = rules_tab.node_results;
  var node_result;
  

  if(typeof cache_item == 'object') {
    index       = rules_tab.tree.currentIndex;
    
    node_result = rules_tab.node_results[index];
    
    rules_tab.textbox_message.value = node_result.getMessage();
    
    var purpose = node_result.getRulePurpose();
    
    if (purpose && purpose.length) rules_tab.textbox_message.value += "\n\nPURPOSE: " + purpose;

    rules_tab.textbox_message.value += "\n\nREQUIREMENT: " + node_result.getRuleRequirement();
    
    rules_tab.textbox_message.value += "\nRULE TYPE: " + node_result.getRuleType();
    
    var cache_nls = OpenAjax.a11y.cache_nls;
    
    var rule = node_result.getRule();
    
    var cache_properties     = rule.cache_properties;
    var cache_properties_len = cache_properties.length;

    OAA_CI.removeChildNodes(rules_tab.treechildren_rule_properties);
    
    var treeitem;
    var treerow;
    var treecell;
    
    var prop;
    var prop_nls;
    var value;
    
    for (var i = 0; i < cache_properties_len; i++) {
    
      prop = cache_properties[i];   

      value = cache_item.getCachePropertyValue(prop);
      
      if (value === null) continue;

      prop_nls = cache_nls.getLabelAndValueNLS(prop, value);

      treeitem = document.createElement('treeitem');
      treerow  = document.createElement('treerow');
      
      treecell = document.createElement('treecell');
      treecell.setAttribute("label", prop_nls.label);
      treerow.appendChild(treecell);
      
      treecell = document.createElement('treecell');
      treecell.setAttribute("label", prop_nls.value);
      treerow.appendChild(treecell);

      treecell = document.createElement('treecell');
      treecell.setAttribute("label", prop_nls.description);
      treerow.appendChild(treecell);

      treeitem.appendChild(treerow);
      rules_tab.treechildren_rule_properties.appendChild(treeitem);
    
    }
  }
}


/**
 * @constructor RulesTab
 *
 * @memberOf OAA_CI.Properties
 *
 * @desc cache_item Object OAA Cache item
 *
 * @param {XULElement}  tabs           - reference to the tabs xul element of the tabbox
 * @param {XULElement}  tabpanels      - reference to the tabpanel xul element of the tabbox
 * @param {String}      tab_label      - title of tab panel
 * @param {Array}       column_Labels  - Array of strings representing column lables
 * @param {Array}       column_flexes  - Array of numbers representing column flex values
 *       
 * @property {Number}        number_of_columns - number of columns in tree 
 * @property {XULEelement}   tabpanel          - reference to the tabpanel dom node 
 * @property {XULEelement}   treecols          - reference to the treecols dom node
 * @property {XULEelement}   treechildren      - reference to the treechildren dom node
 * @property {Object}        current_item      - currently selected cache item
 */
 
OAA_CI.Properties.RulesTab = function createTabRules(tabs, tabpanels, tab_label, column_labels, column_flexes, nls_strings) {

  var i;
  var ordinal = 1;

  var tab;
  var tabpanel;
  var vbox;
  var tree;
  var treecols;
  var treecol;
  var splitter;
  var treechilds;
  var treerow;
  var treecell;

  this.current_cache_item = null;
  
  this.node_results = [];

  this.nls_none             = nls_strings.getString('none');
  this.nls_not_selected     = nls_strings.getString('notSelected');
  this.nls_no_rule_selected = nls_strings.getString('noRuleSelected');
  
  this.number_of_columns = column_labels.length;

  // create Rule tab
  tab = document.createElement('tab');
  tab.setAttribute('label', tab_label);
  tabs.appendChild(tab);

  // create Rule tabpanel
  tabpanel = document.createElement('tabpanel');
  tabpanel.setAttribute("orient", "vertical");
    
  vbox = document.createElement('vbox');
  vbox.setAttribute("flex", "1");
    
  tree = document.createElement('tree');
  tree.setAttribute("rows"   , "4");
  tree.setAttribute("seltype","single"); 
  tree.setAttribute("flex"   ,"1");
  
  tree.addEventListener('select', OAA_CI.Properties.ruleSelectionChange, true) 

  treecols = document.createElement('treecols');

  for (i = 0; i < this.number_of_columns; i++) {
 
    treecol  = document.createElement('treecol');
    treecol.setAttribute("ordinal", ordinal);
    treecol.setAttribute("label",   column_labels[i]);
    treecol.setAttribute("flex",    column_flexes[i]);
    treecols.appendChild(treecol);

    ordinal++;

    // only add splitter if there are more columns
    if ( (i+1) < this.number_of_columns ) {
      splitter = document.createElement('splitter');
      splitter.setAttribute("ordinal", ordinal);
      splitter.setAttribute("class",   "tree-splitter");
      treecols.appendChild(splitter);
    
      ordinal++;
    }  
    
  }  

  tree.appendChild(treecols);
    
  treechildren = document.createElement('treechildren');
        
  treeitem = document.createElement('treeitem');
  treerow  = document.createElement('treerow');
      
  treecell = document.createElement('treecell');
  treecell.setAttribute("label", this.nls_not_selected);
  
  for (i = 1; i < this.number_of_columns; i++) {
 
    treecell = document.createElement('treecell');
    treecell.setAttribute("label", "");
    treerow.appendChild(treecell);
    
  }  

  treerow.appendChild(treecell);

  treeitem.appendChild(treerow);
  treechildren.appendChild(treeitem);
     
  tree.appendChild(treechildren);
    
  vbox.appendChild(tree);
  tabpanel.appendChild(vbox);
  tabpanels.appendChild(tabpanel);

  this.tabs         = tabs;
  this.tabpanel     = tabpanel;
  this.tree         = tree;
  this.treechildren = treechildren;

  var label;
  var textbox;

  label = document.createElement('label');
  label.setAttribute('value', nls_strings.getString('ruleMessage'));
  label.setAttribute('control', 'ID_TEXTBOX_MESSAGE');
  vbox.appendChild(label);

  textbox = document.createElement('textbox');
  textbox.setAttribute('id', 'ID_TEXTBOX_MESSAGE');
  textbox.setAttribute('multiline', 'true');
  textbox.setAttribute('readonly', 'true');
  textbox.setAttribute('rows', '2');;
  vbox.appendChild(textbox);

  this.textbox_message = textbox;

  tree = document.createElement('tree');
  tree.setAttribute("rows"   , "4");
  tree.setAttribute("seltype","single"); 
  tree.setAttribute("flex"   ,"1");
  tree.setAttribute("tooltiptext", nls_strings.getString('tabRulesPropertiesTreeTooltip'));
  
  treecols = document.createElement('treecols');

  treecol  = document.createElement('treecol');
  treecol.setAttribute("ordinal", '1');
  treecol.setAttribute("label",   nls_strings.getString('tabRulesPropertiesColumnLabel1'));
  treecol.setAttribute("flex",    nls_strings.getString('tabRulesPropertiesColumnFlex1'));
  treecols.appendChild(treecol);

  treecol  = document.createElement('treecol');
  treecol.setAttribute("ordinal", '1');
  treecol.setAttribute("label",   nls_strings.getString('tabRulesPropertiesColumnLabel2'));
  treecol.setAttribute("flex",    nls_strings.getString('tabRulesPropertiesColumnFlex2'));
  treecols.appendChild(treecol);

  treecol  = document.createElement('treecol');
  treecol.setAttribute("ordinal", '1');
  treecol.setAttribute("label",   nls_strings.getString('tabRulesPropertiesColumnLabel3'));
  treecol.setAttribute("flex",    nls_strings.getString('tabRulesPropertiesColumnFlex3'));
  treecols.appendChild(treecol);


  tree.appendChild(treecols);

  treechildren = document.createElement('treechildren');
        
  treeitem = document.createElement('treeitem');
  treerow  = document.createElement('treerow');
      
  treecell = document.createElement('treecell');
  treecell.setAttribute("label", this.nls_not_selected);
  
  treerow.appendChild(treecell);
  treeitem.appendChild(treerow);
  treechildren.appendChild(treeitem);
     
  tree.appendChild(treechildren);

  vbox.appendChild(tree);

  this.treechildren_rule_properties = treechildren;
  
};

/**
 * @method RulesTab.clearProperties
 *
 * @memberOf OAA_CI.Properties
 *
 * @desc Clears the rules in the rules tabs
 */
 
OAA_CI.Properties.RulesTab.prototype.clearProperties = function () {

  OAA_CI.removeChildNodes(this.treechildren);
  this.node_results = [];

  var treeitem;
  var treerow;
  var treecell;
        
  treeitem = document.createElement('treeitem');
  treerow  = document.createElement('treerow');
     
  treecell = document.createElement('treecell');
  treecell.setAttribute("label", this.nls_not_selected);
  treerow.appendChild(treecell);
 
  for (var i = 1; i < this.number_of_columns; i++) {
    treecell = document.createElement('treecell');
    treecell.setAttribute("label", "");
    treerow.appendChild(treecell);
  }
      
  treeitem.appendChild(treerow);
  this.treechildren.appendChild(treeitem);

  this.textbox_message.value = this.nls_no_rule_selected;

  OAA_CI.removeChildNodes(this.treechildren_rule_properties);
  this.node_results = [];

  var treeitem;
  var treerow;
  var treecell;
        
  treeitem = document.createElement('treeitem');
  treerow  = document.createElement('treerow');
     
  treecell = document.createElement('treecell');
  treecell.setAttribute("label", this.nls_no_rule_selected);
  treerow.appendChild(treecell);
 
  for (var i = 1; i < this.number_of_columns; i++) {
    treecell = document.createElement('treecell');
    treecell.setAttribute("label", "");
    treerow.appendChild(treecell);
  }
      
  treeitem.appendChild(treerow);
  this.treechildren_rule_properties.appendChild(treeitem);

  this.current_cache_item = null;

};

/**
 * @method RulesTab.updateProperties
 *
 * @memberOf OAA_CI.Properties
 *
 * @desc Shows the properties of an OAA cache item
 *
 * @param {Object}  cache_item  -  OAA cache item object  
 */
 
OAA_CI.Properties.RulesTab.prototype.updateProperties = function (cache_item) {

  this.current_cache_item = cache_item;

  OAA_CI.removeChildNodes(this.treechildren);

  var treeitem      = null;
  var treerow       = null;
  var treecell      = null;
  
  var rule_results = cache_item.getResultRules();
  var rule_results_len = rule_results.length;
  var rr;
  var sev;
  var desc;
 
  if (rule_results_len) {
    
    for (var i = 0; i < rule_results_len; i++) {
        
      rr = rule_results[i];
      this.node_results.push(rr);

      treeitem = document.createElement('treeitem');
      treerow  = document.createElement('treerow');

      treecell = document.createElement('treecell');
      treecell.setAttribute('label',      rr.getSeverityLabel());
      treecell.setAttribute('properties', rr.getSeverityStyle());
      treerow.appendChild(treecell);

      treecell = document.createElement('treecell');
      treecell.setAttribute('label',      rr.getRuleId());
      treerow.appendChild(treecell);

      treecell = document.createElement('treecell');
      treecell.setAttribute('label', rr.getMessage());
      treerow.appendChild(treecell);

      treeitem.appendChild(treerow);

      sub_treechildren = document.createElement('treechildren');
      

      this.treechildren.appendChild(treeitem);
        
    } // endfor
    
  } 
  else {
    treeitem = document.createElement('treeitem');
    treerow  = document.createElement('treerow');
      
    treecell = document.createElement('treecell');
    treecell.setAttribute('label', this.nls_none);
    treerow.appendChild(treecell);
 
    treecell = document.createElement('treecell');
    treecell.setAttribute('label', '');
    treerow.appendChild(treecell);
      
    treeitem.appendChild(treerow);
    this.treechildren.appendChild(treeitem);
  }  

};

/**
 * @constructor EventsTab
 *
 * @memberOf OAA_CI.Properties
 *
 * @desc cache_item Object OAA Cache item
 *
 * @param {XULElement}  tabs           - reference to the tabs xul element of the tabbox
 * @param {XULElement}  tabpanels      - reference to the tabpanel xul element of the tabbox
 * @param {String}      tab_label      - title of tab panel
 * @param {Array}       column_Labels  - Array of strings representing column lables
 * @param {Array}       column_flexes  - Array of numbers representing column flex values
 *       
 * @property {Number}        number_of_columns - number of columns in tree 
 * @property {XULEelement}   tabpanel          - reference to the tabpanel dom node 
 * @property {XULEelement}   treecols          - reference to the treecols dom node
 * @property {XULEelement}   treechildren      - reference to the treechildren dom node
 */
 
OAA_CI.Properties.EventsTab = function createTabRules(tabs, tabpanels, tab_label, column_labels, column_flexes, nls_strings) {

  var i;
  var ordinal = 1;

  var tab;
  var tabpanel;
  var vbox;
  var tree;
  var treecols;
  var treecol;
  var splitter;
  var treechilds;
  var treerow;
  var treecell;
    
  this.nls_none         = nls_strings.getString('none');
  this.nls_not_selected = nls_strings.getString('notSelected');
  
  this.number_of_columns = column_labels.length;

  // create Rule tab
  tab = document.createElement('tab');
  tab.setAttribute('label', tab_label);
  tabs.appendChild(tab);

  // create Rule tabpanel
  tabpanel = document.createElement('tabpanel');
  tabpanel.setAttribute("orient", "vertical");
    
  vbox = document.createElement('vbox');
  vbox.setAttribute("flex", "1");
    
  tree = document.createElement('tree');
  tree.setAttribute("rows"   , "10");
  tree.setAttribute("seltype","single"); 
  tree.setAttribute("flex"   ,"1");
    
  treecols = document.createElement('treecols');

  for (i = 0; i < this.number_of_columns; i++) {
 
    treecol  = document.createElement('treecol');
    treecol.setAttribute("ordinal", ordinal);
    treecol.setAttribute("label",   column_labels[i]);
    treecol.setAttribute("flex",    column_flexes[i]);
    treecols.appendChild(treecol);

    ordinal++;

    // only add splitter if there are more columns
    if ( (i+1) < this.number_of_columns ) {
      splitter = document.createElement('splitter');
      splitter.setAttribute("ordinal", ordinal);
      splitter.setAttribute("class",   "tree-splitter");
      treecols.appendChild(splitter);
    
      ordinal++;
    }  
    
  }  

  tree.appendChild(treecols);
    
  treechildren = document.createElement('treechildren');
        
  treeitem = document.createElement('treeitem');
  treerow  = document.createElement('treerow');
      
  treecell = document.createElement('treecell');
  treecell.setAttribute("label", this.nls_not_selected);
  
  for (i = 1; i < this.number_of_columns; i++) {
 
    treecell = document.createElement('treecell');
    treecell.setAttribute("label", "");
    treerow.appendChild(treecell);
    
  }  

  treerow.appendChild(treecell);

  treeitem.appendChild(treerow);
  treechildren.appendChild(treeitem);
     
  tree.appendChild(treechildren);
    
  vbox.appendChild(tree);
  tabpanel.appendChild(vbox);
  tabpanels.appendChild(tabpanel);
    
  this.tabs         = tabs;
  this.tabpanel     = tabpanel;
  this.treechildren = treechildren;
    
};

/**
 * @method EventsTab.clearProperties
 *
 * @memberOf OAA_CI.Properties
 *
 * @desc Clears the event information in the event tab
 */
 
OAA_CI.Properties.EventsTab.prototype.clearProperties = function () {

  OAA_CI.removeChildNodes(this.treechildren);

  var treeitem;
  var treerow;
  var treecell;
        
  treeitem = document.createElement('treeitem');
  treerow  = document.createElement('treerow');
     
  treecell = document.createElement('treecell');
  treecell.setAttribute("label", this.nls_not_selected);
  treerow.appendChild(treecell);
 
  for (var i = 1; i < this.number_of_columns; i++) {
    treecell = document.createElement('treecell');
    treecell.setAttribute("label", "");
    treerow.appendChild(treecell);
  }
      
  treeitem.appendChild(treerow);
  this.treechildren.appendChild(treeitem);

};

/**
 * @method EventsTab.updateProperties
 *
 * @memberOf OAA_CI.Properties
 *
 * @desc Shows the event properties of a cache item
 *
 * @param {Array}  events - Array of event objects
 */
 
OAA_CI.Properties.EventsTab.prototype.updateProperties = function (events) {

  OAA_CI.removeChildNodes(this.treechildren);

  var treeitem     = null;
  var treerow      = null;
  var treecell     = null;
          
  var events_len = events.length;
  var event;
 
  if (events_len) {
    
    for (var i = 0; i < events_len; i++) {
        
      event = events[i];
        
      treeitem = document.createElement('treeitem');
      treerow  = document.createElement('treerow');
    
      treecell = document.createElement('treecell');
      treecell.setAttribute('label', event.label);
      treerow.appendChild(treecell);

      treecell = document.createElement('treecell');
      treecell.setAttribute('label',      event.on_element);
      treecell.setAttribute('properties', event.on_element_style);
      treerow.appendChild(treecell);

      treecell = document.createElement('treecell');
      treecell.setAttribute('label',      event.on_ancestor);
      treecell.setAttribute('properties', event.on_ancestor_style);
      treerow.appendChild(treecell);
            
      treeitem.appendChild(treerow);
      this.treechildren.appendChild(treeitem);
        
    } // endfor
    
  } 
  else {
    treeitem = document.createElement('treeitem');
    treerow  = document.createElement('treerow');
      
    treecell = document.createElement('treecell');
    treecell.setAttribute('label', this.nls_none);
    treerow.appendChild(treecell);
 
    treecell = document.createElement('treecell');
    treecell.setAttribute('label', '');
    treerow.appendChild(treecell);
      
    treecell = document.createElement('treecell');
    treecell.setAttribute('label', '');
    treerow.appendChild(treecell);
      
    treeitem.appendChild(treerow);
    this.treechildren.appendChild(treeitem);
  }  

};

/**
 * @constructor PropertiesTab
 *
 * @memberOf OAA_CI.Properties
 *
 * @desc Generic properties tab panel
 *
 * @param {XULElement}  tabs              - reference to the tabs xul element of the tabbox
 * @param {XULElement}  tabpanels         - reference to the tabpanel xul element of the tabbox
 * @param {String}      tab_label         - title of tab panel
 * @param {String}      property_label    - Used as the label for the first column
 * @param {Array}       column_Labels     - Array of strings representing column lables
 * @param {Array}       column_flexes     - Array of numbers representing column flex values
 * 
 * @property {Number}        number_of_columns - number of columns in tree 
 * @property {XULEelement}   tabpanel          - reference to the tabpanel dom node 
 * @property {XULEelement}   treecols          - reference to the treecols dom node
 * @property {XULEelement}   treechildren      - reference to the treechildren dom node
 */

OAA_CI.Properties.PropertiesTab = function (tabs, tabpanels, tab_label, column_labels, column_flexes, nls_strings) {

  var i;
  var ordinal = 1;
  
  var tab;
  var vbox;
  var tree;
  var treecols;
  var splitter;
  var tabpanel;
  var treerow;
  var treecell;

  this.nls_none         = nls_strings.getString('none');
  this.nls_not_selected = nls_strings.getString('notSelected');
  
  this.number_of_columns = column_labels.length;

  // create Rule tab
    
  tab = document.createElement('tab');
  tab.setAttribute("label", tab_label);
  tabs.appendChild(tab);

  // create Rule tabpanel
  tabpanel = document.createElement('tabpanel');
  tabpanel.setAttribute("orient", "vertical");
    
  vbox = document.createElement('vbox');
  vbox.setAttribute("flex", "1");
    
  tree = document.createElement('tree');
  tree.setAttribute("rows",    "10");
  tree.setAttribute("seltype", "single"); 
  tree.setAttribute("flex",    "1");
  treecols  = document.createElement('treecols');
    
  for (i = 0; i < column_labels.length; i++) {
 
    // No splitter on first column
    if (i != 0) {
      splitter = document.createElement('splitter');
      splitter.setAttribute("ordinal", ordinal);
      splitter.setAttribute("class",   "tree-splitter");
      treecols.appendChild(splitter);
    
      ordinal++;
    }
    
    treecol  = document.createElement('treecol');
    treecol.setAttribute("ordinal", ordinal);
    treecol.setAttribute("label",   column_labels[i]);
    treecol.setAttribute("flex",    column_flexes[i]);
    treecols.appendChild(treecol);

    ordinal++;
   
  }  

  
  tree.appendChild(treecols);
    
  treechildren = document.createElement('treechildren');
    
  treeitem = document.createElement('treeitem');
  treerow  = document.createElement('treerow');
      
  treecell = document.createElement('treecell');
  treecell.setAttribute("label", this.nls_not_selected);
  treerow.appendChild(treecell);
 
  for (i = 1; i < column_labels.length; i++) {
    treecell = document.createElement('treecell');    
    treecell.setAttribute("label", "");
    treerow.appendChild(treecell);
  }  
        
  treeitem.appendChild(treerow);
  treechildren.appendChild(treeitem);
    
  tree.appendChild(treechildren);
    
  vbox.appendChild(tree);
  tabpanel.appendChild(vbox);
  tabpanels.appendChild(tabpanel);
  
  this.vbox             = vbox;
  this.treechildren     = treechildren;
  this.tabpanels        = tabpanels;
  
};


/**
 * @method PropertiesTab.clearProperties
 *
 * @memberOf OAA_CI.Properties
 *
 * @desc Clears the rules in the rules tabs
 */
 
OAA_CI.Properties.PropertiesTab.prototype.clearProperties = function () {

  OAA_CI.removeChildNodes(this.treechildren);

  var treeitem     = null;
  var treerow      = null;
  var treecell     = null;
        
  treeitem = document.createElement('treeitem');
  treerow  = document.createElement('treerow');
     
  treecell = document.createElement('treecell');
  treecell.setAttribute("label", this.nls_not_selected);
  treerow.appendChild(treecell);
     
  for (var i = 1; i < this.number_of_columns; i++) {
    treecell = document.createElement('treecell');
    treecell.setAttribute("label", "");
    treerow.appendChild(treecell);
  }
      
  treeitem.appendChild(treerow);
  this.treechildren.appendChild(treeitem);

};

/**
 * @method PropertiesTab.updateProperties
 *
 * @memberOf OAA_CI.Properties
 *
 * @desc Shows the properties of an OAA cache item
 *
 * @param {Array}  items  - Array of properties for this tab   
 */
 
OAA_CI.Properties.PropertiesTab.prototype.updateProperties = function (items) {

  OAA_CI.removeChildNodes(this.treechildren);

  var treeitem     = null;
  var treerow      = null;
  var treecell     = null;
        
  var items_len = items.length;
  var item;
 
  if (items_len) {
    
    for (var i = 0; i < items_len; i++) {
        
      item = items[i];
        
      treeitem = document.createElement('treeitem');
      treerow  = document.createElement('treerow');
  
      treecell = document.createElement('treecell');
      treecell.setAttribute('label', item.label);
      treerow.appendChild(treecell);

      treecell = document.createElement('treecell');
      treecell.setAttribute('label', item.value);
      treerow.appendChild(treecell);

      if (this.number_of_columns > 2) {
        treecell = document.createElement('treecell');
        treecell.setAttribute('label', item.description);
        treerow.appendChild(treecell);
      }  
            
      treeitem.appendChild(treerow);
      this.treechildren.appendChild(treeitem);
        
    } // endfor
    
  } 
  else {
    treeitem = document.createElement('treeitem');
    treerow  = document.createElement('treerow');
      
    treecell = document.createElement('treecell');
    treecell.setAttribute('label', this.nls_none);
    treerow.appendChild(treecell);
 
    treecell = document.createElement('treecell');    
    treecell.setAttribute('label', ' ');
    treerow.appendChild(treecell);
      
    treeitem.appendChild(treerow);
    this.treechildren.appendChild(treeitem);
  }           
};

/**
 * @constructor PropertiesTabPanel
 *
 * @memberOf OAA_CI.Properties
 *
 * @desc cache_item Object OAA Cache item
 *
 * @param {String}  id      -  id of xul element to add tab panel
 *
 * @param {Object}  config  -  Object with a set of boolean properties defining which item trees are created
 *                             Properties: rules, attributes, properties, style and events
 *       
 * @property {XULElement}   tabbox               - reference to the tabbox dom node 
 * @property {XULElement}   tabs                 - reference to the tabs dom node
 * @property {XULElement}   tabpanels            - reference to the tabpanel dom node
 * @property {XULElement}   vbox                 - reference to rules tab panel 
 *
 * @property {RulesTab}       rules_tab       - reference to rules tab panel 
 * @property {PropertiesTab}  attributes_tab  - reference to attributes tab panel 
 * @property {PropertiesTab}  properties_tab  - reference to properties tab panel
 * @property {PropertiesTab}  style_tab       - reference to style tab panel
 * @property {PropertiesTab}  events_tab      - reference to events tab panel 
 *
 * @example
 *
 */

OAA_CI.Properties.PropertiesTabPanel = function(id, config) {

  var label;
  var vbox;
  var tabbox;
  var tabs;
  var tabpanels;
  var nls_strings;

  var column_labels;
  var column_flexes;

  this.rules_tab      = null;
  this.attributes_tab = null;
  this.properties_tab = null;
  this.style_tab      = null;
  this.events_tab     = null;

  // Get references to the tree column widgets
  vbox = document.getElementById(id);
  
  nls_strings = document.getElementById('ID_STRING_ELEMENT_PROPERTIES');

  var nls_none         = nls_strings.getString('none');
  var nls_not_selected = nls_strings.getString('notSelected');

  var nls_panel_label             = nls_strings.getString('panelLabel');
  var nls_panel_accesskey         = nls_strings.getString('panelAccesskey');
  
  var nls_tab_rules                 = nls_strings.getString('tabRules');
  var nls_tab_rules_column_label_1  = nls_strings.getString('tabRulesColumnLabel1');
  var nls_tab_rules_column_label_2  = nls_strings.getString('tabRulesColumnLabel2');
  var nls_tab_rules_column_label_3  = nls_strings.getString('tabRulesColumnLabel3');
  var nls_tab_rules_column_flex_1   = nls_strings.getString('tabRulesColumnFlex1');
  var nls_tab_rules_column_flex_2   = nls_strings.getString('tabRulesColumnFlex2');
  var nls_tab_rules_column_flex_3   = nls_strings.getString('tabRulesColumnFlex3');
  
  var nls_tab_attributes                = nls_strings.getString('tabAttributes');
  var nls_tab_attributes_column_label_1 = nls_strings.getString('tabAttributesColumnLabel1');
  var nls_tab_attributes_column_label_2 = nls_strings.getString('tabAttributesColumnLabel2');
  var nls_tab_attributes_column_flex_1  = nls_strings.getString('tabAttributesColumnFlex1');
  var nls_tab_attributes_column_flex_2  = nls_strings.getString('tabAttributesColumnFlex2');
  
  var nls_tab_properties                = nls_strings.getString('tabProperties');
  var nls_tab_properties_column_label_1 = nls_strings.getString('tabPropertiesColumnLabel1');
  var nls_tab_properties_column_label_2 = nls_strings.getString('tabPropertiesColumnLabel2');
  var nls_tab_properties_column_label_3 = nls_strings.getString('tabPropertiesColumnLabel3');
  var nls_tab_properties_column_flex_1  = nls_strings.getString('tabPropertiesColumnFlex1');
  var nls_tab_properties_column_flex_2  = nls_strings.getString('tabPropertiesColumnFlex2');
  var nls_tab_properties_column_flex_3  = nls_strings.getString('tabPropertiesColumnFlex3');
  
  var nls_tab_style                = nls_strings.getString('tabStyle');
  var nls_tab_style_column_label_1 = nls_strings.getString('tabStyleColumnLabel1');
  var nls_tab_style_column_label_2 = nls_strings.getString('tabStyleColumnLabel2');
  var nls_tab_style_column_flex_1  = nls_strings.getString('tabStyleColumnFlex1');
  var nls_tab_style_column_flex_2  = nls_strings.getString('tabStyleColumnFlex2');
  
  var nls_tab_events                = nls_strings.getString('tabEvents');
  var nls_tab_events_column_label_1 = nls_strings.getString('tabEventsColumnLabel1');
  var nls_tab_events_column_label_2 = nls_strings.getString('tabEventsColumnLabel2');
  var nls_tab_events_column_label_3 = nls_strings.getString('tabEventsColumnLabel3');
  var nls_tab_events_column_flex_1  = nls_strings.getString('tabEventsColumnFlex1');
  var nls_tab_events_column_flex_2  = nls_strings.getString('tabEventsColumnFlex2');
  var nls_tab_events_column_flex_3  = nls_strings.getString('tabEventsColumnFlex3');
  
  label = document.createElement('label');
  label.setAttribute('value',     nls_panel_label);
  label.setAttribute('accesskey', nls_panel_accesskey);
  label.setAttribute('control',  'ID_TABBOX_PROPERTIES');
  label.setAttribute('class', 'header indent');
  label.setAttribute('property', 'PROPERTY_LABEL');
  vbox.appendChild(label);

  tabbox = document.createElement('tabbox');
  tabbox.id = "ID_TABBOX_PROPERTIES";
  tabbox.iselectedIndex = 1;
  tabbox.flex = "1";
  
  tabs      = document.createElement('tabs');
  tabpanels = document.createElement('tabpanels');

  if (!config || config.rules) {
    column_labels = [nls_tab_rules_column_label_1, nls_tab_rules_column_label_2, nls_tab_rules_column_label_3];
    column_flexes = [nls_tab_rules_column_flex_1,  nls_tab_rules_column_flex_2,  nls_tab_rules_column_flex_3];
    this.rules_tab = new OAA_CI.Properties.RulesTab(tabs, tabpanels, nls_tab_rules, column_labels, column_flexes, nls_strings);
    
  }
  
  if (!config || config.attributes) {
    column_labels = [nls_tab_attributes_column_label_1, nls_tab_attributes_column_label_2];
    column_flexes = [nls_tab_attributes_column_flex_1,  nls_tab_attributes_column_flex_2];
    this.attributes_tab = new OAA_CI.Properties.PropertiesTab(tabs, tabpanels, nls_tab_attributes, column_labels, column_flexes, nls_strings);
  }
  
  if (!config || config.properties) {
    column_labels = [nls_tab_properties_column_label_1, nls_tab_properties_column_label_2, nls_tab_properties_column_label_3];
    column_flexes = [nls_tab_properties_column_flex_1,  nls_tab_properties_column_flex_2,  nls_tab_properties_column_flex_3];
    this.properties_tab = new OAA_CI.Properties.PropertiesTab(tabs, tabpanels, nls_tab_properties, column_labels, column_flexes, nls_strings);
  }
  
  if (!config || config.style) {
    column_labels = [nls_tab_style_column_label_1, nls_tab_style_column_label_2];
    column_flexes = [nls_tab_style_column_flex_1,  nls_tab_style_column_flex_2];
    this.style_tab = new OAA_CI.Properties.PropertiesTab(tabs, tabpanels, nls_tab_style, column_labels, column_flexes, nls_strings);
  }

  if (!config || config.events) {
    column_labels = [nls_tab_events_column_label_1, nls_tab_events_column_label_2, nls_tab_events_column_label_3];
    column_flexes = [nls_tab_events_column_flex_1,  nls_tab_events_column_flex_2,  nls_tab_events_column_flex_3];
    this.events_tab = new OAA_CI.Properties.EventsTab(tabs, tabpanels, nls_tab_events, column_labels, column_flexes, nls_strings);
  }

  tabbox.appendChild(tabs);
  tabbox.appendChild(tabpanels);
  vbox.appendChild(tabbox);
  
  this.tabbox    = tabbox;
  this.tabs      = tabs;
  this.tabpanels = tabpanels;
  this.vbox      = vbox;
  
};

/**
 * @method PropertiesTabPanel.show
 *
 * @memberOf OAA_CI.Properties
 *
 * @desc Shows the properties panel
 */
 
OAA_CI.Properties.PropertiesTabPanel.prototype.show = function() {
  this.vbox.style.display = "";
}

/**
 * @method PropertiesTabPanel.hide
 *
 * @memberOf OAA_CI.Properties
 *
 * @desc Hides the properties panel
 */
 
OAA_CI.Properties.PropertiesTabPanel.prototype.hide = function() {
  this.vbox.style.display = "none";
}

/**
 * @method clearProperties
 *
 * @memberOf OAA_CI.Properties.PropertiesTabPanel
 *
 * @desc Remove data from Cache Property panel
 *       and turn off highlighting
 */

OAA_CI.Properties.PropertiesTabPanel.prototype.clearProperties = function () {

  if (this.rules_tab)           this.rules_tab.clearProperties();
  if (this.attributes_tab) this.attributes_tab.clearProperties();
  if (this.properties_tab) this.properties_tab.clearProperties();
  if (this.style_tab)           this.style_tab.clearProperties();
  if (this.events_tab)         this.events_tab.clearProperties();
  
  OAA_CI.turnOffHighlighting();
  
};

/**
 * @method updateProperties
 *
 * @memberOf OAA_CI.Properties.PropertiesTabPanel
 *
 * @desc Updates the property panels with the information form a OAA cache item object 
 *
 * @param {Object}  cache_item  -  OAA cache item object   
 */

OAA_CI.Properties.PropertiesTabPanel.prototype.updateProperties = function (cache_item) {

  OAA_CI.Properties.properties_panel = this;

  this.clearProperties();
  
  if (this.rules_tab)           this.rules_tab.updateProperties(cache_item);
  if (this.attributes_tab) this.attributes_tab.updateProperties(cache_item.getAttributes());
  if (this.properties_tab) this.properties_tab.updateProperties(cache_item.getCacheProperties());
  if (this.style_tab)           this.style_tab.updateProperties(cache_item.getStyle());
  if (this.events_tab)         this.events_tab.updateProperties(cache_item.getEvents());
  
  OAA_CI.highlightCacheItem(cache_item);
    
};
